home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-01-04 | 5.7 KB | 204 lines | [TEXT/PICN] |
- # This program is a filter for Icon allocation history files. It tabulates
- # the number of allocations by type and the total amount of storage
- # (in bytes) by type.
- #
- # It takes an Icon allocation history file from standard input and writes to
- # standard output. There is a command-line option -d that produces
- # some debugging output.
- #
- # At the moment, it's still a bit ad hoc and inevitably incomplete.
- #
- # Some assumptions are made about where newlines occur -- specifically
- # that verification commands are on single lines and that refresh and
- # garbage collection data are on multiple lines.
- #
-
- global cmds, highlights, lastlen, alloccnt, alloctot, collections
- global mmunits, diagnose
-
- procedure main(opts)
-
- diagnose := if opts[1] == "-d" then write else 1
-
- cmds := 'cefLlRrSsTtux"XAF' # command characters
- highlights := '%$Y' # highlight commands
- mmunits := 4 # (for most systems)
-
- lastlen := table() # last size
- alloccnt := table(0) # count of allocations
- alloctot := table(0) # total allocation
- collections := list(4,0) # garbage collection counts
-
- every alloccnt[!cmds] := 0
- every alloctot[!cmds] := 0
-
- cmds ++:= highlights
-
- while line := read() do { # input from MemMon history file
- line ? { # note: coded for extensions
- if region := tab(upto('{')) then { # skip refresh sequence
- collections[region] +:= 1
- while line := read() | stop("**** premature eof") do
- line ? if upto('#!') then break next
- }
- case move(1) of {
-
- "=": next # skip verification command
- "#": next # skip comment
- "<": { # skip refresh sequence
- while line := read() | stop("**** premature eof") do
- line ? if upto('#>') then break next
- }
- ";": next # skip pause command
- "!" | ">": next # resynchronize (edited file)
-
- default: { # data to process
- move(-1) # back off from move(1) above
- if mmuits := integer(tab(upto('<'))) then {
- while line := read() | stop("**** premature eof") do
- line ? if upto('#>') then break next
- }
- else {
- repeat { # process allocation
- tab(many(' ')) # skip blanks (old files)
- if pos(0) then break next
- skip := process(tab(upto(cmds) + 1)) |
- stop("*** unexpected data: ",line)
- move(skip)
- }
- }
- }
- }
- }
- }
-
- display()
-
- end
-
- # Display a table of allocation data
- #
- procedure display()
-
- static namemap
- static col1, col2, gutter # column widths
-
- initial { # map of codes to type names
- namemap := table("*** undefined ***")
- namemap["c"] := "cset"
- namemap["e"] := "table element tv"
- namemap["f"] := "file"
- namemap["L"] := "list header"
- namemap["l"] := "list element"
- namemap["R"] := "record"
- namemap["r"] := "real number"
- namemap["S"] := "set header"
- namemap["s"] := "set element"
- namemap["T"] := "table header"
- namemap["t"] := "table element"
- namemap["u"] := "substring tv"
- namemap["x"] := "refresh block"
- namemap["\""] := "string"
- namemap["X"] := "co-expression"
- namemap["A"] := "alien block"
- namemap["F"] := "free space"
-
- col1 := 16 # name field
- col2 := 10 # number field
- gutter := repl(" ",6)
- }
-
- write(, # write column headings
- "\n",
- left("type",col1),
- right("number",col2),
- gutter,
- right("bytes",col2),
- gutter,
- right("average",col2),
- gutter,
- right("% bytes",col2),
- "\n"
- )
-
- alloccnt := sort(alloccnt,3) # get the data
- alloctot := sort(alloctot,3)
-
- cnttotal := 0
- tottotal := 0
-
- every i := 2 to *alloccnt by 2 do {
- cnttotal +:= alloccnt[i]
- tottotal +:= alloctot[i]
- }
-
- while write( # write the data
- left(namemap[get(alloccnt)],col1), # name
- right(cnt := get(alloccnt),col2), # number of allocations
- gutter,
- get(alloctot) & right(tot := get(alloctot),col2), # space allocated
- gutter,
- fix(tot,cnt,col2),
- gutter,
- fix(100.0 * tot,tottotal,col2)
- )
-
- write( # write totals
- "\n",
- left("total:",col1),
- right(cnttotal,col2),
- gutter,
- right(tottotal,col2),
- gutter,
- fix(tottotal,cnttotal,col2)
- )
-
- totalcoll := 0 # garbage collections
- every totalcoll +:= !collections
- write("\n",left("collections:",col1),right(totalcoll,col2))
- if totalcoll > 0 then {
- write(left(" static region:",col1),right(collections[1],col2))
- write(left(" string region:",col1),right(collections[2],col2))
- write(left(" block region:",col1),right(collections[3],col2))
- wr}
-
- return
- end
-
- # Process datm
- #
- procedure process(s)
-
- s ? {
- tab(upto('+') + 1) # skip address
- len := tab(many(&digits)) | &null
- cmd := move(1)
-
- if cmd == !highlights then return 2 else {
- # if given len is nonstring, scale
- if cmd ~== "\"" then \len *:= mmunits
- alloccnt[cmd] +:= 1
- (/len := lastlen[cmd]) | (lastlen[cmd] := len)
- diagnose(&errout,"cmd=",cmd,", len=",len)
- alloctot[cmd] +:= len
- return 0
- }
- }
- end
-
- # Format floating-point number.
- #
- procedure fix(i,j,w)
-
- if j = 0 then return repl(" ",w)
- r := real(i) / j
- if r < 0.001 then return repl(" ",w - 5) || "0.000"
- string(r) ? {
- int := tab(upto('.'))
- &pos +:= 1
- dec := tab(0)
- }
- return right(int,w - 4) || "." || left(dec,3,"0")
-
- end
-